{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "8419f04e-f945-491d-9526-6aebbabbad6a",
   "metadata": {},
   "source": [
    "# Typed State\n",
    "\n",
    "In this example we're going to be using state-typing with instructor + Burr to generate social media posts from youtube videos.\n",
    "\n",
    "First, let's define some pydantic models. Note you'll need the env var `OPENAI_API_KEY` set. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "d62b0737-683c-4748-8b55-c15402aa1b2f",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: burr[pydantic] in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (0.24.0)\n",
      "Requirement already satisfied: instructor in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (1.4.1)\n",
      "Requirement already satisfied: openai in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (1.44.0)\n",
      "Requirement already satisfied: rich in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (13.7.1)\n",
      "\u001b[33mWARNING: burr 0.24.0 does not provide the extra 'pydantic'\u001b[0m\u001b[33m\n",
      "\u001b[0mRequirement already satisfied: aiohttp<4.0.0,>=3.9.1 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from instructor) (3.9.5)\n",
      "Requirement already satisfied: docstring-parser<0.17,>=0.16 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from instructor) (0.16)\n",
      "Requirement already satisfied: jiter<0.6.0,>=0.5.0 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from instructor) (0.5.0)\n",
      "Requirement already satisfied: pydantic<3.0.0,>=2.8.0 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from instructor) (2.8.2)\n",
      "Requirement already satisfied: pydantic-core<3.0.0,>=2.18.0 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from instructor) (2.20.1)\n",
      "Requirement already satisfied: tenacity<9.0.0,>=8.4.1 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from instructor) (8.5.0)\n",
      "Requirement already satisfied: typer<1.0.0,>=0.9.0 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from instructor) (0.12.3)\n",
      "Requirement already satisfied: anyio<5,>=3.5.0 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from openai) (4.4.0)\n",
      "Requirement already satisfied: distro<2,>=1.7.0 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from openai) (1.9.0)\n",
      "Requirement already satisfied: httpx<1,>=0.23.0 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from openai) (0.27.0)\n",
      "Requirement already satisfied: sniffio in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from openai) (1.3.1)\n",
      "Requirement already satisfied: tqdm>4 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from openai) (4.66.4)\n",
      "Requirement already satisfied: typing-extensions<5,>=4.11 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from openai) (4.12.2)\n",
      "Requirement already satisfied: markdown-it-py>=2.2.0 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from rich) (3.0.0)\n",
      "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from rich) (2.18.0)\n",
      "Requirement already satisfied: aiosignal>=1.1.2 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from aiohttp<4.0.0,>=3.9.1->instructor) (1.3.1)\n",
      "Requirement already satisfied: attrs>=17.3.0 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from aiohttp<4.0.0,>=3.9.1->instructor) (23.2.0)\n",
      "Requirement already satisfied: frozenlist>=1.1.1 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from aiohttp<4.0.0,>=3.9.1->instructor) (1.4.1)\n",
      "Requirement already satisfied: multidict<7.0,>=4.5 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from aiohttp<4.0.0,>=3.9.1->instructor) (6.0.5)\n",
      "Requirement already satisfied: yarl<2.0,>=1.0 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from aiohttp<4.0.0,>=3.9.1->instructor) (1.9.4)\n",
      "Requirement already satisfied: idna>=2.8 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from anyio<5,>=3.5.0->openai) (3.7)\n",
      "Requirement already satisfied: certifi in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from httpx<1,>=0.23.0->openai) (2024.7.4)\n",
      "Requirement already satisfied: httpcore==1.* in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from httpx<1,>=0.23.0->openai) (1.0.5)\n",
      "Requirement already satisfied: h11<0.15,>=0.13 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from httpcore==1.*->httpx<1,>=0.23.0->openai) (0.14.0)\n",
      "Requirement already satisfied: mdurl~=0.1 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from markdown-it-py>=2.2.0->rich) (0.1.2)\n",
      "Requirement already satisfied: annotated-types>=0.4.0 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from pydantic<3.0.0,>=2.8.0->instructor) (0.7.0)\n",
      "Requirement already satisfied: click>=8.0.0 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from typer<1.0.0,>=0.9.0->instructor) (8.1.7)\n",
      "Requirement already satisfied: shellingham>=1.3.0 in /Users/elijahbenizzy/.pyenv/versions/3.12.0/envs/burr-3-12/lib/python3.12/site-packages (from typer<1.0.0,>=0.9.0->instructor) (1.5.4)\n",
      "\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.2\u001b[0m\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpython3.12 -m pip install --upgrade pip\u001b[0m\n",
      "Note: you may need to restart the kernel to use updated packages.\n"
     ]
    }
   ],
   "source": [
    "%pip install 'burr[pydantic]' instructor openai rich"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "66fe6bbc-3c75-4ff6-9974-4d82109dc47a",
   "metadata": {},
   "source": [
    "# Imports/setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "c3da83a6-0047-4599-aa0c-c4d7a0cc7e78",
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import AsyncGenerator, Generator, Optional, Tuple, Union\n",
    "\n",
    "import instructor\n",
    "import openai\n",
    "from pydantic import BaseModel, Field\n",
    "from pydantic.json_schema import SkipJsonSchema\n",
    "from rich.console import Console\n",
    "from youtube_transcript_api import YouTubeTranscriptApi\n",
    "\n",
    "from burr.core import Application, ApplicationBuilder, action\n",
    "from burr.core.action import (\n",
    "    AsyncStreamingResultContainer,\n",
    "    StreamingResultContainer,\n",
    "    streaming_action,\n",
    ")\n",
    "from burr.integrations.pydantic import PydanticTypingSystem\n",
    "import json\n",
    "import time\n",
    "from rich import print_json\n",
    "from IPython.display import clear_output"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1c5d6d06-3a82-44df-b4fe-82c95b3d3d05",
   "metadata": {},
   "source": [
    "# Constructs\n",
    "\n",
    "Let's define some pydantic models to use -- these will help shape our application"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "90258678-b33e-4e84-9a22-c7a6d29aca5d",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Concept(BaseModel):\n",
    "    term: str = Field(description=\"A key term or concept mentioned.\")\n",
    "    definition: str = Field(description=\"A brief definition or explanation of the term.\")\n",
    "    timestamp: float = Field(description=\"Timestamp when the concept is explained.\")\n",
    "\n",
    "class SocialMediaPost(BaseModel):\n",
    "    \"\"\"A social media post about a YouTube video generated its transcript\"\"\"\n",
    "\n",
    "    topic: str = Field(description=\"Main topic discussed.\")\n",
    "    hook: str = Field(\n",
    "        description=\"Statement to grab the attention of the reader and announce the topic.\"\n",
    "    )\n",
    "    body: str = Field(\n",
    "        description=\"The body of the social media post. It should be informative and make the reader curious about viewing the video.\"\n",
    "    )\n",
    "    concepts: list[Concept] = Field(\n",
    "        description=\"Important concepts about Hamilton or Burr mentioned in this post -- please have at least 1\",\n",
    "        min_items=0,\n",
    "        max_items=3,\n",
    "        validate_default=False,\n",
    "    )\n",
    "    key_takeaways: list[str] = Field(\n",
    "        description=\"A list of informative key takeways for the reader -- please have at least 1\",\n",
    "        min_items=0,\n",
    "        max_items=4,\n",
    "        validate_default=False,\n",
    "    )\n",
    "    youtube_url: SkipJsonSchema[Union[str, None]] = None"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "03534c74-aa1f-4a1d-91c7-7c6328228c8d",
   "metadata": {},
   "source": [
    "# State Type\n",
    "\n",
    "Using those, we'll define a core pydantic model that sets up the central schema for our application. Note these are optional, they won't be set when our application starts!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "5158c112-f054-4881-89dd-12ca7f1e0e79",
   "metadata": {},
   "outputs": [],
   "source": [
    "class ApplicationState(BaseModel):\n",
    "    # Make these have defaults as they are only set in actions\n",
    "    transcript: Optional[str] = Field(\n",
    "        description=\"The full transcript of the YouTube video.\", default=None\n",
    "    )\n",
    "    post: Optional[SocialMediaPost] = Field(\n",
    "        description=\"The generated social media post.\", default=None\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8e0d745-6561-4331-9a5d-86948fee706d",
   "metadata": {},
   "source": [
    "# Write an action to transcribe a youtube URL\n",
    "\n",
    "Note we take in a youtube URL + the state in the format we want, and write to `transcript`. We actually read nothing, as the transcript is an input.\n",
    "Different than normal Burr, we actually mutate the model we send in (this allows us to leverage pydantic validation)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "df35e278-3578-4611-a9de-c3948911ff70",
   "metadata": {},
   "outputs": [],
   "source": [
    "@action.pydantic(reads=[], writes=[\"transcript\"])\n",
    "def get_youtube_transcript(state: ApplicationState, youtube_url: str) -> ApplicationState:\n",
    "    \"\"\"Get the official YouTube transcript for a video given its URL\"\"\"\n",
    "    _, _, video_id = youtube_url.partition(\"?v=\")\n",
    "\n",
    "    transcript = YouTubeTranscriptApi.get_transcript(video_id, languages=[\"en\"])\n",
    "    state.transcript = \" \".join([f\"ts={entry['start']} - {entry['text']}\" for entry in transcript])\n",
    "    return state"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f5dbcaf5-5471-44b0-82e3-c4b32f01a115",
   "metadata": {},
   "source": [
    "# Write an action to stream back pydantic models\n",
    "\n",
    "We specify the state input type, state output type, and the stream type, streaming it all back using [instructors streaming capability](https://python.useinstructor.com/concepts/partial/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "4737d8b1-e1c1-472c-bc01-a47d328797d8",
   "metadata": {},
   "outputs": [],
   "source": [
    "@streaming_action.pydantic(\n",
    "    reads=[\"transcript\"],\n",
    "    writes=[\"post\"],\n",
    "    state_input_type=ApplicationState,\n",
    "    state_output_type=ApplicationState,\n",
    "    stream_type=SocialMediaPost,\n",
    ")\n",
    "def generate_post(\n",
    "    state: ApplicationState, llm_client\n",
    ") -> Generator[Tuple[SocialMediaPost, Optional[ApplicationState]], None, None]:\n",
    "\n",
    "    transcript = state.transcript\n",
    "    response = llm_client.chat.completions.create_partial(\n",
    "        model=\"gpt-4o-mini\",\n",
    "        response_model=SocialMediaPost,\n",
    "        messages=[\n",
    "            {\n",
    "                \"role\": \"system\",\n",
    "                \"content\": \"Analyze the given YouTube transcript and generate a compelling social media post.\",\n",
    "            },\n",
    "            {\"role\": \"user\", \"content\": transcript},\n",
    "        ],\n",
    "        stream=True,\n",
    "    )\n",
    "    final_post: SocialMediaPost = None  # type: ignore\n",
    "    for post in response:\n",
    "        final_post = post\n",
    "        yield post, None\n",
    "\n",
    "    yield final_post, state"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "968daa7a-c83f-4890-b775-513dbc347068",
   "metadata": {},
   "source": [
    "# Wire together in an application\n",
    "\n",
    "We  specify the application to have type `ApplicationState` as the state, and pass it an initial value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "11bdf44a-5ff2-4cd3-87b9-175eb68de8e4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 12.0.0 (20240704.0754)\n",
       " -->\n",
       "<!-- Pages: 1 -->\n",
       "<svg width=\"167pt\" height=\"176pt\"\n",
       " viewBox=\"0.00 0.00 166.85 175.80\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 171.8)\">\n",
       "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-171.8 162.85,-171.8 162.85,4 -4,4\"/>\n",
       "<!-- get_youtube_transcript -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>get_youtube_transcript</title>\n",
       "<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M146.85,-102.2C146.85,-102.2 12,-102.2 12,-102.2 6,-102.2 0,-96.2 0,-90.2 0,-90.2 0,-77.6 0,-77.6 0,-71.6 6,-65.6 12,-65.6 12,-65.6 146.85,-65.6 146.85,-65.6 152.85,-65.6 158.85,-71.6 158.85,-77.6 158.85,-77.6 158.85,-90.2 158.85,-90.2 158.85,-96.2 152.85,-102.2 146.85,-102.2\"/>\n",
       "<text text-anchor=\"middle\" x=\"79.42\" y=\"-78.1\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">get_youtube_transcript</text>\n",
       "</g>\n",
       "<!-- generate_post -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>generate_post</title>\n",
       "<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M121.35,-36.6C121.35,-36.6 37.5,-36.6 37.5,-36.6 31.5,-36.6 25.5,-30.6 25.5,-24.6 25.5,-24.6 25.5,-12 25.5,-12 25.5,-6 31.5,0 37.5,0 37.5,0 121.35,0 121.35,0 127.35,0 133.35,-6 133.35,-12 133.35,-12 133.35,-24.6 133.35,-24.6 133.35,-30.6 127.35,-36.6 121.35,-36.6\"/>\n",
       "<text text-anchor=\"middle\" x=\"79.42\" y=\"-12.5\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">generate_post</text>\n",
       "</g>\n",
       "<!-- get_youtube_transcript&#45;&gt;generate_post -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>get_youtube_transcript&#45;&gt;generate_post</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M73.3,-65.18C72.8,-59.95 72.6,-54.07 72.7,-48.32\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"76.19,-48.61 73.23,-38.43 69.2,-48.23 76.19,-48.61\"/>\n",
       "</g>\n",
       "<!-- input__youtube_url -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>input__youtube_url</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" stroke-dasharray=\"5,2\" points=\"143.85,-167.8 15,-167.8 15,-131.2 143.85,-131.2 143.85,-167.8\"/>\n",
       "<text text-anchor=\"middle\" x=\"79.42\" y=\"-143.7\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">input: youtube_url</text>\n",
       "</g>\n",
       "<!-- input__youtube_url&#45;&gt;get_youtube_transcript -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>input__youtube_url&#45;&gt;get_youtube_transcript</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M79.42,-130.78C79.42,-125.55 79.42,-119.67 79.42,-113.92\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"82.93,-114.03 79.43,-104.03 75.93,-114.03 82.93,-114.03\"/>\n",
       "</g>\n",
       "<!-- generate_post&#45;&gt;get_youtube_transcript -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>generate_post&#45;&gt;get_youtube_transcript</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M85.54,-36.92C86.04,-42.15 86.25,-48.02 86.15,-53.78\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"82.66,-53.5 85.63,-63.67 89.65,-53.87 82.66,-53.5\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<burr.core.application.Application at 0x12fff20c0>"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "llm_client = instructor.from_openai(openai.OpenAI())\n",
    "app = (\n",
    "    ApplicationBuilder()\n",
    "    .with_actions(\n",
    "        get_youtube_transcript,\n",
    "        generate_post.bind(llm_client=llm_client),\n",
    "    )\n",
    "    .with_transitions(\n",
    "        (\"get_youtube_transcript\", \"generate_post\"),\n",
    "        (\"generate_post\", \"get_youtube_transcript\"),\n",
    "    )\n",
    "    .with_entrypoint(\"get_youtube_transcript\")\n",
    "    .with_typing(PydanticTypingSystem(ApplicationState))\n",
    "    .with_state(ApplicationState())\n",
    "    .with_tracker(project=\"youtube-post\")\n",
    "    .build()\n",
    ")\n",
    "# in case we want to access the state\n",
    "assert isinstance(app.state.data, ApplicationState)\n",
    "app"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "29eb49bc-f1c0-4172-831d-bd748ac90548",
   "metadata": {},
   "source": [
    "# Run it!\n",
    "\n",
    "Now we can run it!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "ba1486aa-f79f-4e02-959c-ffc0ba58b6ac",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">{</span>\n",
       "  <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">\"topic\"</span>: <span style=\"color: #008000; text-decoration-color: #008000\">\"Burr Framework Overview\"</span>,\n",
       "  <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">\"hook\"</span>: <span style=\"color: #008000; text-decoration-color: #008000\">\"Ever faced challenges while debugging AI applications? Here's a solution!\"</span>,\n",
       "  <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">\"body\"</span>: <span style=\"color: #008000; text-decoration-color: #008000\">\"Dive into the world of agent applications with Burr! In this quick overview, we explore how Burr helps you debug failing AI calls and track state effectively. Learn to build a graph that connects actions and states, allowing you to resume your application exactly where you left off. Whether it’s fixing an error mid-run or replaying past actions, Burr's observability features enhance your development workflow. Ready to optimize your debugging process? Check out the full video to unravel the potential of Burr!\"</span>,\n",
       "  <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">\"concepts\"</span>: <span style=\"font-weight: bold\">[</span>\n",
       "    <span style=\"font-weight: bold\">{</span>\n",
       "      <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">\"term\"</span>: <span style=\"color: #008000; text-decoration-color: #008000\">\"Agent Application\"</span>,\n",
       "      <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">\"definition\"</span>: <span style=\"color: #008000; text-decoration-color: #008000\">\"A system that models states and actions to create decision-making processes.\"</span>,\n",
       "      <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">\"timestamp\"</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">105.479</span>\n",
       "    <span style=\"font-weight: bold\">}</span>,\n",
       "    <span style=\"font-weight: bold\">{</span>\n",
       "      <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">\"term\"</span>: <span style=\"color: #008000; text-decoration-color: #008000\">\"State Object\"</span>,\n",
       "      <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">\"definition\"</span>: <span style=\"color: #008000; text-decoration-color: #008000\">\"An object that holds the state information for actions to read and write during execution.\"</span>,\n",
       "      <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">\"timestamp\"</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">145.56</span>\n",
       "    <span style=\"font-weight: bold\">}</span>,\n",
       "    <span style=\"font-weight: bold\">{</span>\n",
       "      <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">\"term\"</span>: <span style=\"color: #008000; text-decoration-color: #008000\">\"Graph Representation\"</span>,\n",
       "      <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">\"definition\"</span>: <span style=\"color: #008000; text-decoration-color: #008000\">\"A structural representation of actions and their interconnections in an agent system, depicted as nodes and edges.\"</span>,\n",
       "      <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">\"timestamp\"</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">179.28</span>\n",
       "    <span style=\"font-weight: bold\">}</span>\n",
       "  <span style=\"font-weight: bold\">]</span>,\n",
       "  <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">\"key_takeaways\"</span>: <span style=\"font-weight: bold\">[</span>\n",
       "    <span style=\"color: #008000; text-decoration-color: #008000\">\"Burr allows near-instantaneous debugging without restarting from scratch.\"</span>,\n",
       "    <span style=\"color: #008000; text-decoration-color: #008000\">\"The framework promotes building a stateful graph structure for actions.\"</span>,\n",
       "    <span style=\"color: #008000; text-decoration-color: #008000\">\"Use local tracking to effortlessly monitor and interact with your agent's state.\"</span>\n",
       "  <span style=\"font-weight: bold\">]</span>,\n",
       "  <span style=\"color: #000080; text-decoration-color: #000080; font-weight: bold\">\"youtube_url\"</span>: <span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">null</span>\n",
       "<span style=\"font-weight: bold\">}</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m{\u001b[0m\n",
       "  \u001b[1;34m\"topic\"\u001b[0m: \u001b[32m\"Burr Framework Overview\"\u001b[0m,\n",
       "  \u001b[1;34m\"hook\"\u001b[0m: \u001b[32m\"Ever faced challenges while debugging AI applications? Here's a solution!\"\u001b[0m,\n",
       "  \u001b[1;34m\"body\"\u001b[0m: \u001b[32m\"Dive into the world of agent applications with Burr! In this quick overview, we explore how Burr helps you debug failing AI calls and track state effectively. Learn to build a graph that connects actions and states, allowing you to resume your application exactly where you left off. Whether it’s fixing an error mid-run or replaying past actions, Burr's observability features enhance your development workflow. Ready to optimize your debugging process? Check out the full video to unravel the potential of Burr!\"\u001b[0m,\n",
       "  \u001b[1;34m\"concepts\"\u001b[0m: \u001b[1m[\u001b[0m\n",
       "    \u001b[1m{\u001b[0m\n",
       "      \u001b[1;34m\"term\"\u001b[0m: \u001b[32m\"Agent Application\"\u001b[0m,\n",
       "      \u001b[1;34m\"definition\"\u001b[0m: \u001b[32m\"A system that models states and actions to create decision-making processes.\"\u001b[0m,\n",
       "      \u001b[1;34m\"timestamp\"\u001b[0m: \u001b[1;36m105.479\u001b[0m\n",
       "    \u001b[1m}\u001b[0m,\n",
       "    \u001b[1m{\u001b[0m\n",
       "      \u001b[1;34m\"term\"\u001b[0m: \u001b[32m\"State Object\"\u001b[0m,\n",
       "      \u001b[1;34m\"definition\"\u001b[0m: \u001b[32m\"An object that holds the state information for actions to read and write during execution.\"\u001b[0m,\n",
       "      \u001b[1;34m\"timestamp\"\u001b[0m: \u001b[1;36m145.56\u001b[0m\n",
       "    \u001b[1m}\u001b[0m,\n",
       "    \u001b[1m{\u001b[0m\n",
       "      \u001b[1;34m\"term\"\u001b[0m: \u001b[32m\"Graph Representation\"\u001b[0m,\n",
       "      \u001b[1;34m\"definition\"\u001b[0m: \u001b[32m\"A structural representation of actions and their interconnections in an agent system, depicted as nodes and edges.\"\u001b[0m,\n",
       "      \u001b[1;34m\"timestamp\"\u001b[0m: \u001b[1;36m179.28\u001b[0m\n",
       "    \u001b[1m}\u001b[0m\n",
       "  \u001b[1m]\u001b[0m,\n",
       "  \u001b[1;34m\"key_takeaways\"\u001b[0m: \u001b[1m[\u001b[0m\n",
       "    \u001b[32m\"Burr allows near-instantaneous debugging without restarting from scratch.\"\u001b[0m,\n",
       "    \u001b[32m\"The framework promotes building a stateful graph structure for actions.\"\u001b[0m,\n",
       "    \u001b[32m\"Use local tracking to effortlessly monitor and interact with your agent's state.\"\u001b[0m\n",
       "  \u001b[1m]\u001b[0m,\n",
       "  \u001b[1;34m\"youtube_url\"\u001b[0m: \u001b[3;35mnull\u001b[0m\n",
       "\u001b[1m}\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "_, streaming_container = app.stream_result(\n",
    "    halt_after=[\"generate_post\"],\n",
    "    inputs={\"youtube_url\": \"https://www.youtube.com/watch?v=hqutVJyd3TI\"},\n",
    ")\n",
    "for post in streaming_container:\n",
    "    assert isinstance(post, SocialMediaPost)\n",
    "    clear_output(wait=True)\n",
    "    obj = post.model_dump()\n",
    "    json_str = json.dumps(obj, indent=2)\n",
    "    print_json(json_str)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
